//
//  structAndClass.swift
//  swiftStudy
//
//  Created by unisedu on 16/4/1.
//  Copyright © 2016年 CaoFei. All rights reserved.
//
/*
类和结构体有很多共性
1。定义属性存储数据
2. 定义方法执行功能处理
3. 定义下标，通过下标访问他们的值
4. 初始化他们的状态
5. 通过扩展（Extension）扩展其功能
6. 遵守协议（Protocol） 协议提供一种特定的标准功能

类比结构体多出的功能
1.能够继承另一个类
2.能够核对运行期间对象的类型
3.析构对象释放资源
4。引用计数允许一个类实例有多个引用

*/
//MARK:- aaa
//FIXME: aaaaaaaa
//TODO: 

import UIKit
//定义 Point
struct Point{
    var x = 0.0 , y = 0.0
}
class structAndClass: NSObject {
   
    
    
    func show(){
        //创建对象
        let someResolution = Resolution()
        
        let someVideoMode = VideoMode()
        
        var rangeOfThreeItems = FixedLengthRange(firstValue : 0 , length : 3)
        
        rangeOfThreeItems.firstValue = 6
        //常量属性是不可以修改的
        //常量对象也不能修改属性
        let rangeOfThreeItems2 = FixedLengthRange(firstValue : 0 , length : 3)

        let manager = DataManager()
        manager.data += "Some data"
        manager.data += "Some more data"
        
        print(manager.importer.fileName)
        
        
        
        
        var square = Rect (origin : Point (x:0.0,y:0.0), size : Size (width:10.0,height:10.0))
        let initialSquareCenter = square.center
        square.center = Point(x:15.0,y:15.0)
        print("square.orgin is now at (\(square.origin.x),\(square.origin.y))")
        
    }
    
    
}


//定义类和结构体
class SomeClass{
    //class definition goes here
}

struct SomeStructure{
    //structure definition goes here
}

//实例
//一般要给属性初始值
struct Resolution{
    var width = 0
    var height = 0
}

class VideoMode{
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name : String?
}






//属性 类似OC中合成存取器 但有区别
/*
主要作用是存储数据，可以常量和变量
*/
struct FixedLengthRange{
    var firstValue : Int
    let length : Int
}


/*延时存储属性是初始化时候不分配值，直到第一次使用它，用的几率低考虑使用这个属性，使用多的话不建议使用
属性 @lazy声明
*/

class DataImporter {
    var fileName = "data.txt"
}

class DataManager {
    lazy var importer = DataImporter()
    var data = ""
}




//计算属性
//有的时候一些属性是通过其他属性计算得出得，通过get和setf访问器对其访问

//定义 Point
struct Point{
    var x = 0.0 , y = 0.0
}
//定义 Size
struct Size{
    var width = 0.0 , height = 0.0
}

//定义 Rect
struct Rect {
    var origin = Point()
    var size = Size()
    var center : Point{
        get{
            let centerX = origin.x + (size.width/2)
            let centerY = origin.y + (size.height/2)
            return Point(x:centerX , y:centerY)
        }
        set(newCenter){
            origin.x = newCenter.x - (size.width/2)
            origin.y = newCenter.y - (size.height/2)
        }
    }
}




//属性观察者
//为了监听属性的变化，swift通过了属性观察者
//willSet观察者是在存储之前调用
//didSet新值存储后调用

class StepCounter{
    var totalSteps : Int = 0 {
        willSet(newTotalSteps){
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet{
            if totalSteps > oldValue{
                print("Add \(totalSteps - oldValue) steps")
            }
        }
    }
}

let stepCounter = StepCounter()
stepCounter.totalSteps = 200
stepCounter.totalSteps = 360
stepCounter.totalSteps = 896



//静态属性在结构体中使用static定义，类中使用class定义

//struct SomeStructure1{
//    static var storedTypeProperty = "Some Value"
//    static var computedTypeProperty : Int {
//    //return an int value here
//    }
//}
//
//class SomeClass1{
//    class var computedTypeProperty : Int {
//        //return an Int value here
//    }
//}
//调用的时候可以直接使用类和结构体名调用


//实例
struct AudioChannel {
    static let thresholdLevel = 10
    static var maxInputLevelForAllChannels = 0
    var currentLevel : Int = 0 {
        didSet {
            if currentLevel > AudioChannel.thresholdLevel{
                currentLevel = AudioChannel.thresholdLevel
            }
            if  currentLevel > AudioChannel.maxInputLevelForAllChannels{
                AudioChannel.maxInputLevelForAllChannels = currentLevel
            }
        }
    }
}

var leftChannel = AudioChannel()
var rightChannel = AudioChannel()
//不能直接调用静态属性
leftChannel.currentLevel = 7
print(leftChannel.currentLevel)
print(AudioChannel.maxInputLevelForAllChannels)


//方法 swift中的方法是与特定类型（类和结构体）相关的函数
//1.实例方法
class Counter{
    var count = 0
    func increment(){
        count++
    }
    func incrementBy(amount : Int){
        count += amount
    }
    func reset(){
        count = 0;
    }
}

let counter = Counter()
counter.increment()
counter.incrementBy(5)
counter.reset()


//2.使用self

struct Point1 {
    var x = 0.0 , y = 0.0
    func isToTheRightOfX(x : Double) -> Bool {
        return self.x > x
    }
}

let somePoint = Point1(x : 4.0 , y : 5.0)
if somePoint.isToTheRightOfX(1.0) {
    print ("This point is to the right of the line where x == 1.0")
}



//下标 类似字典的下标， 也可以在类和结构体中定义
//1.定义下标
//subscript(index : Int) -> Int {
//    get{
//        //return an appropriate subscript value here
//    }
//    set(newValue){
//        //perform a suitable setting action here
//    }
//}
//2.只读下标
struct TimesTable {
    let multiplier : Int
    //类似get方法，这样写也可以省略get
    subscript(index : Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier : 3)
print ("six times three is \(threeTimesTable[6])")

//继承 swift中的类能够继承其他类的属性、方法等

//1.定义基类
class Vehicle{
    var numberOfWheeLs : Int
    var maxPassengers : Int
    func description() -> String {
        return "\(numberOfWheeLs) wheeLs; up to \(maxPassengers) passengers"
    }
    
    init(){
        numberOfWheeLs = 0
        maxPassengers = 1
    }
    
}
let someVehicel = Vehicle()


//2.定义子类
//class SomeClass:SomeSuperClass{
//    //class definition goes here
//}

class Bicycle:Vehicle{
    override init(){
        super.init()//初始化父类
        numberOfWheeLs=2
    }
}

let bicycle = Bicycle()
print("Bicycle:\(bicycle.description())")


//3.重写（overriding） 子类能够重写父类的方法，属性、下标。
//3.1方法重写

class Car:Vehicle{
    var speed : Double = 0.0
    override init(){
        super.init()
        maxPassengers = 5
        numberOfWheeLs = 4
        
    }
    override func description() -> String {
        return super.description() + ";" + "traveling at \(speed) mph"
    }
}

let car = Car()
print ("Car : \(car.description())")


//3.2属性重写 下标是属性的一种特殊的情况
class SpeedLimitedCar : Car {
    override var speed : Double {
        get {
            return super.speed
        }
        set{
            super.speed = min (newValue , 40.0)
        }
    }
}

let limitedCar = SpeedLimitedCar()
limitedCar.speed = 60.0
print("SpeedLimitedCar : \(limitedCar.description())")

